home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
bump.exe
/
BUMP.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-10
|
17KB
|
753 lines
/* Function definitions for
BUMP 1.1
the Beginners Understandable Matrix Package
for Borland C++
*/
#include <iostream.h> // for cout
#include <ctype.h> // for isdigit()
#include <stdio.h> // for fgets()
#include <alloc.h> // for coreleft()
#include <stdlib.h> // for atof()
#include <conio.h> // for cprintf()
#include <string.h> // for strlen()
#include "bump.h"
extern unsigned _stklen = 64000;
int vcount = 0;
///////////////// The Vector member functions /////////////////////////
Vector::Vector(int anr, int anc, char atemp, int afr, int afc)
{
if(anr != 1 && anc != 1){
cout << "Either the number of rows or the number of columns must be 1.\n";
return;
}
which = vcount++;
nr = anr;
nc = anc;
temp = atemp;
fr = afr;
fc = afc;
lr = fr + nr - 1;
lc = fc + nc - 1;
nelem = nr + nc - 1;
if(nelem < 0 || nelem > 16000){
cout << nelem << "is an illegal number of elements for a vector.\n";
return;
}
if(nelem == 0)
v = 0;
else if((v = new float[nelem]) == 0)
cout << "Out of memory.\n";
}
Vector::Vector(Vector& a)
{
int i;
which = vcount++;
nr = a.nr;
nc = a.nc;
temp = a.temp;
fr = a.fr;
fc = a.fc;
lr = a.lr;
lc = a.lc;
nelem = a.nelem;
/* Before the "operator " functions return, they must "destroy" the Temp
vector they created. But since many are returning Temp, C++ calls this
function to make a copy of Temp. That call is implicit; the programmer
does not explicitly do it. After that call, the destructor is called,
also implicitly, to destroy the original Temp. This copy will then be
returned. The following device detects that the vector being copied is a
temporary vector doomed to immediate destruction, so it just captures the
v array as its own and sets a.v = 0, so that the destructor won't hurt
it. */
if(a.temp == 'y'){
v = a.v;
a.v = 0;
}
else{
if((v = new float[nelem]) == 0){
cout << "Out of memory trying to create vector" << which <<".\n";
exit(1);
}
for(i = 0; i < nelem; i++)
v[i] = a.v[i];
}
}
Vector::~Vector()
{
if(v != 0 ) delete v;
}
// Free heap memory
void Vector::freeh()
{
if(v != 0 ) delete v;
v = 0;
}
int Vector::ReadA(char *filename)
{
FILE *fp;
int i,j,k;
char s[241],field[30];
if((fp = fopen(filename,"rt")) == 0){
cerr << "Cannot open " << filename << ".\n";
return(ERR);
}
fgets(s,240,fp);
j = 0;
for(i = 0; i < nelem; i++){
if(getfloat(v[i],fp,s,j) == ERR){
cerr << "Out of data in " << filename << ".\n";
break;
}
}
fclose(fp);
return(OK);
}
void Vector::Display(char *title,int width, int decimalPlaces)
{
int i, nperline;
char fmt[20];
if(strlen(title) > 0) printf("\n%s\n", title);
nperline = 79/width;
sprintf(fmt,"%s%d.%df", "%",width,decimalPlaces);
for(i = 0;i<nelem;i++){
printf(fmt,v[i]);
if(i % nperline == nperline - 1) printf("\n");
}
}
Vector& Vector::operator = (Vector& a)
{
int i;
int s = (nelem < a.nelem) ? nelem : a.nelem;
for(i = 0; i < s; i++){
v[i] = a.v[i];
}
a.freet();
return(*this);
}
Vector Vector::operator ~ () // Transposition
{
int i;
Vector Temp(nc,nr,'y',fc,fr);
for(i = 0; i < nelem; i++)
Temp.v[i] = v[i];
return(Temp);
}
float& Vector::operator [](int i)
{
if(v==0){
cerr << "Error: Reference to a deleted vector.\n";
exit(1);
}
if(nc == 1){
if (fr > i || lr < i){
cerr << "Illegal vector index: " << i << "\n";
exit(1);
}
return(v[i - fr]);
}
else{
if (fc > i || lc < i){
cerr << "illegal vector index: " << i << "\n";
exit(1);
}
return(v[i -fc]);
}
}
Vector Vector::operator - (Vector &a)
{
int i;
if(fr != a.fr || lr != a.lr){
cout << "vector dimensions do not match in + operator.\n";
}
Vector Temp(nr,nc,'y');
for(i = 0; i < nelem; i++)
Temp.v[i] = v[i] - a.v[i];
freet();
return (Temp);
}
//////////////// Friends of Vector (only) /////////////////////////
/* operator + and operator - are written differently to illustrate
the two methods.
*/
Vector operator + (Vector &a, Vector &b)
{
int i;
if(b.fr != a.fr || b.lr != a.lr){
cout << "vector dimensions do not match in + operator.\n";
}
Vector Temp(a.nr,a.nc,'y');
for(i = 0; i < a.nelem; i++)
Temp.v[i] = a.v[i] + b.v[i];
a.freet();
b.freet();
return (Temp);
}
Vector operator * (float a, Vector &b)
{
int i;
Vector Temp(b.nr,b.nc,'y');
for(i = 0; i < b.nelem; i++)
Temp.v[i] = a * b.v[i];
b.freet();
return (Temp);
}
Vector operator / (Vector &a, float b)
{
int i;
float recip;
Vector Temp(a.nr,a.nc,'y');
recip = 0;
if(b == 0) printf("Division by zero in Vector operator /.\n");
else recip = 1./b;
for(i = 0; i < a.nelem; i++)
Temp.v[i] = a.v[i]*recip;
a.freet();
return (Temp);
}
////////////////////// THE MATRIX MEMBER FUNCTIONS /////////////////////////
Matrix::Matrix(int anr, int anc, char atemp, int afr, int afc)
{
int i;
which = vcount++;
nr = anr;
nc = anc;
temp = atemp;
fr = afr;
fc = afc;
lr = fr + nr - 1;
lc = fc + nc - 1;
if((m = new float* [nr]) == 0) goto gripe;
m -= fr;
for(i = fr; i <= lr; i++){
if((m[i] = new float [nc]) == 0) goto gripe;
m[i] -= fc;
}
return;
gripe:
cout << "Out of memory on array number " << which << ".\n";
exit(1);
}
Matrix::Matrix(Matrix& a)
{
int i,j;
which = vcount++;
nr = a.nr;
nc = a.nc;
temp = a.temp;
fr = a.fr;
fc = a.fc;
lr = a.lr;
lc = a.lc;
// See the note at this point in Vector::Vector(Vector& a), which
// applies here also.
if(a.temp == 'y'){
m = a.m;
a.m = 0;
}
else{
if((m = new float* [nr]) == 0) goto gripe;
m -= fr;
for(i = fr; i <= lr; i++){
if((m[i] = new float [nc]) == 0) goto gripe;
m[i] -= fc;
}
for(i = fr; i <= lr; i++){
for(j = fc; j <= lc; j++)
m[i][j] = a.m[i][j];
}
}
return;
gripe:
cout << "Out of memory on array number " << which << ".\n";
exit(1);
}
Matrix::~Matrix()
{
freeh();
}
void Matrix::freeh()
{
int i;
if(m == 0) return;
for(i = fr; i <= lr; i++)
delete m[i];
delete m;
m = 0;
}
int Matrix::ReadA(char *filename)
{
FILE *fp;
int i,j,k;
char s[241];
if((fp = fopen(filename,"rt")) == 0){
cerr << "Cannot open " << filename << ".\n";
return(ERR);
}
fgets(s,240,fp);
k = 0;
for(i = fr; i <= lr; i++){
for(j = fc; j <= lc; j++){
if(getfloat(m[i][j],fp,s,k) == ERR) break;
}
}
fclose(fp);
return(OK);
}
void Matrix::Display(char *title,int width, int decimalPlaces)
{
int i, j, nperline;
char fmt[20];
if(strlen(title) > 0) printf("\n%s\n", title);
nperline = 79/width;
sprintf(fmt,"%s%d.%df", "%",width,decimalPlaces);
for(i = fr; i <= lr; i++){
for(j = fc; j <= lc; j++){
printf(fmt,m[i][j]);
if((j - fc % nperline == nperline -1) && j < lc)
printf("\n");
}
printf("\n");
}
}
Matrix& Matrix::operator = (Matrix& a)
{
int i,j,nrmin,ncmin;
nrmin = nr < a.nr ? nr : a.nr;
ncmin = nc < a.nc ? nc : a.nc;
if(nr != a.nr || nc != a.nc)
cout << "Equating matrices of unequal size.\n";
for(i = 0; i < nrmin; i++){
for(j = 0; j < ncmin; j++)
m[fr+i][fc+j] = a.m[a.fr+i][a.fc+j];
}
a.freet();
return(*this);
}
Matrix Matrix::operator ~ () //Transposition
{
int i,j;
Matrix Temp(nc,nr,'y',fc,fr);
for(i = fr; i <= lr; i++){
for(j = fc; j <= lc; j++)
Temp.m[j][i] = m[i][j];
}
return(Temp);
}
float * Matrix::operator [](int i)
{
if(m==0){
cerr << "Error: Reference to a deleted matrix.\n";
exit(1);
}
if(i < fr || i > lr ){
cerr << "illegal matrix row index: " << i << "." << "\n";
cerr << "returning first row. \n";
return m[fr];
}
return(m[i]);
}
Matrix Matrix::operator ! () // Inversion
{
double determinant;
if(temp == 'n'){
Matrix Temp(*this);
Temp.temp = 'y';
Temp.invert();
return(Temp);
}
else{ // If this matrix is temporary, turn i